package com.dctp.ems.controller;

import com.dctp.common.cache.ContractCache;
import com.dctp.common.controller.BaseController;
import com.dctp.common.core.RedisManager;
import com.dctp.common.utils.StringUtil;
import com.dctp.common.vo.JsonResult;
import com.dctp.common.vo.PageResult;
import com.dctp.common.vo.RedisKey;
import com.jfinal.core.Path;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.aop.Before;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import com.dctp.common.utils.CollectUtil;
import com.dctp.common.utils.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

@Path("/activity")
public class ActivityController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ActivityController.class);
    /**
     * GET /activity/list
     * 分页查询活动
     * 参数：page, pageSize, name, status
     */
    public void list() {
        int page = getInt("currentPage", 1);
        int pageSize = getInt("pageSize", 10);
        String name = getPara("name", "");
        Integer status = getParaToInt("status", null);
        StringBuilder where = new StringBuilder(" WHERE 1=1 ");
        List<Object> params = new java.util.ArrayList<>();
        if (!name.isEmpty()) {
            where.append(" AND name LIKE ?");
            params.add("%" + name + "%");
        }
        if (status != null) {
            where.append(" AND status = ?");
            params.add(status);
        }

        String searchSymbol = getPara("symbol");
        if (StringUtil.isNotEmpty(searchSymbol)) {
            where.append(" AND symbol = ?");
            params.add(searchSymbol);
        }

        Integer direction = getParaToInt("direction");
        if (null != direction) {
            where.append(" AND direction = ?");
            params.add(direction);
        }

        String startTime = getPara("start_time");
        String endTime = getPara("end_time");

        if (StringUtil.isNotEmpty(startTime)) {
            where.append(" AND create_time >= ?");
            params.add(startTime);
        }
        if (StringUtil.isNotEmpty(endTime)) {
            where.append(" AND create_time <= ?");
            params.add(endTime);
        }


        String select = "SELECT * ";
        String from = "FROM dctp_activity" + where + " ORDER BY id DESC";
        var p = Db.paginate(page, pageSize, select, from, params.toArray());

        if (CollectUtil.isNotEmpty(p.getList())) {
            p.getList().forEach(item-> {
                Long parentId = item.getLong("parent_id");
                if (parentId == 0) {
                    //获取最后一个子流程的触发价格
                    BigDecimal lastProducePrice;
                    Record lastChild = Db.findFirst("SELECT produce_price,up_down_point FROM dctp_activity WHERE parent_id = ? and status = 2 and produce_price > 0 " +
                            " and begin_time is not null order by id desc limit 1 ",item.getLong("id"));
                    if (lastChild == null) {
                        lastProducePrice = item.getBigDecimal("produce_price");
                    }else {
                        lastProducePrice =  lastChild.getBigDecimal("produce_price");
//                        lastProducePrice = lastProducePrice.subtract(lastChild.getBigDecimal("up_down_point"));
                    }
                    item.set("lastProductPrice",lastProducePrice);
                }

                String symbol = item.getStr("symbol");
                item.set("symbol_name", ContractCache.getNameBySymbol(symbol));
            });
        }

        renderJson(JsonResult.successWithData(
            new PageResult<>(p.getList(), p.getTotalRow(), pageSize, page)
        ));
    }

    /**
     * POST /activity/save
     * 新增或更新活动（有id为更新，无id为新增）
     */
    @Before(Tx.class)
    public void save() {
        Record body = jsonBody();
        body.remove("symbol_name");
        Long id = body.getLong("id");
        String beginTime = body.getStr("begin_time");
        String endTime = body.getStr("end_time");
        LocalDateTime bt = null;
        if (beginTime != null && endTime != null) {
            try {
                bt = DateUtil.parse(beginTime, "yyyy-MM-dd HH:mm:ss");
                LocalDateTime et = DateUtil.parse(endTime, "yyyy-MM-dd HH:mm:ss");
                if (bt.isAfter(et)) {
                    renderJson(JsonResult.failWithMessage("开始时间不能大于结束时间"));
                    return;
                }
            } catch (Exception e) {
                renderJson(JsonResult.failWithMessage("时间格式错误"));
                return;
            }
        }

        if (null == bt) {
            renderJson(JsonResult.failWithMessage("时间格式错误"));
            return;
        }



        body.set("update_time", DateUtil.now());
        String symbol = body.getStr("symbol");
        Long existId = Db.queryLong("select id from dctp_activity where symbol = ? and status = 1 limit 1", symbol);
        if (null != existId) {
            if (id == null || !Objects.equals(id,existId)) {
                renderJson(JsonResult.fail("同合约存在进行中的活动，不能进行此操作"));
                return;
            }
        }
        body.remove("lastProductPrice");

        if (id == null) {
            String name = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            body.set("name",name);
            body.remove("id");
            body.set("create_time", DateUtil.now());
            boolean ok = Db.save("dctp_activity", body);
            renderJson(ok ? JsonResult.success() : JsonResult.failWithMessage("保存失败"));
        } else {

            Record db = Db.findById("dctp_activity", id);
            LocalDateTime dbBeginTime = db.getLocalDateTime("begin_time");

            boolean ok = Db.update("dctp_activity", body);
            if (ok) {
                if (!dbBeginTime.isEqual(bt)) {
                    //修改了时间，清掉缓存
                    String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    String key = String.format(RedisKey.ACTIVITY_SYMBOL_PRICE,db.get("id"),localDate,symbol);
                    RedisManager.getInstance().del(key);
                    logger.warn("修改开始时间，清理缓存：{}",key);
                }
                renderJson(JsonResult.success());
            }else {
                renderJson(JsonResult.failWithMessage("更新失败"));
            }
        }
    }

    /**
     * POST /activity/delete/:id
     * 删除单个活动
     */
    @Before(Tx.class)
    public void delete() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }

        Record activity = Db.findById("dctp_activity", id);
        if (null == activity) {
            renderJson(JsonResult.failWithMessage("活动不存在"));
            return;
        }

        Long parentId = activity.getLong("parent_id");
        if (parentId == 0) {
            Db.delete("delete from dctp_activity where parent_id = ?", id);
        }
        boolean delOk = Db.deleteById("dctp_activity", id);
        if (!delOk) {
            throw new RuntimeException("删除失败");
        }
        //删除缓存
        String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String key = String.format(RedisKey.ACTIVITY_SYMBOL_PRICE,activity.get("id"),localDate,activity.getStr("symbol"));
        RedisManager.getInstance().del(key);

        renderJson(JsonResult.success());
    }

    /**
     * GET /activity/detail/:id
     * 获取单个活动详情
     */
    public void detail() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        Record rec = Db.findById("dctp_activity", id);
        renderJson(rec != null ? JsonResult.successWithData(rec) : JsonResult.failWithMessage("未找到记录"));
    }



    public void all() {
        List<Record> list = Db.find("SELECT * FROM dctp_activity where parent_id = 0 ORDER BY id DESC");
        renderJson(JsonResult.successWithData(CollectUtil.convert(list,r->r.getColumns())));
    }


    @Before(Tx.class)
    public void updateChildProcess() {

        Record body = jsonBody();
        BigDecimal winPoint = body.getBigDecimal("win_point");
        if (winPoint == null ) {
            renderJson(JsonResult.fail("请填写盈利点位"));
            return;
        }

        BigDecimal upDownPoint = body.getBigDecimal("up_down_point");
        if (upDownPoint == null || upDownPoint.compareTo(BigDecimal.ZERO) == 0) {
            renderJson(JsonResult.failWithMessage("涨跌点位不能为0"));
            return;
        }

        Integer duration = body.getInt("duration");
        if (duration == null || duration <= 0) {
            renderJson(JsonResult.failWithMessage("持续时间需要大于0"));
            return;
        }

        Integer direction = upDownPoint.compareTo(BigDecimal.ZERO) > 0 ? 2 : 1;
        Long parentId = body.getLong("parent_id");
        if (null == parentId) {
            renderJson(JsonResult.failWithMessage("请选择主流程进行添加"));
            return;
        }

        Record parent = Db.findById("dctp_activity", parentId);
        if (null == parent) {
            renderJson(JsonResult.failWithMessage("主流程不存在"));
            return;
        }
//
//        if (parent.getInt("status") != 1) {
//            renderJson(JsonResult.failWithMessage("主流程状态异常"));
//            return;
//        }

        Long id = body.getLong("id");
        if (null == id) {
            //主流程
           Record record = new Record();
           String name = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
           Integer childCount = Db.queryInt("select count(id) from dctp_activity where parent_id = ? ", parentId);
           if (childCount == null) childCount = 0;

            Record child = Db.findFirst("select * from dctp_activity where parent_id = ? order by id desc limit 1 ", parentId);
            BigDecimal producePrice;
            if (null != child) {
               if (child.getInt("status") < 2) {
                   renderJson(JsonResult.failWithMessage("存在未结束的子流程，不能添加"));
                   return;
               }
               producePrice = child.getBigDecimal("produce_price");
           }else {
               producePrice = Db.queryBigDecimal("select produce_price from dctp_activity where id = ? ", parentId);
           }

           //获取produce_price
            if (null == producePrice) {
                producePrice = BigDecimal.ZERO;
            }

           record.set("name",name + "-" + (childCount + 1))
                   .set("parent_id",parentId)
                   .set("create_time", DateUtil.now())
                   .set("update_time", DateUtil.now())
                   .set("status",1)
                   .set("up_down_point",upDownPoint)
                   .set("produce_price",producePrice.add(upDownPoint))
                   .set("symbol",parent.get("symbol"))
                   .set("duration",duration)
                   .set("win_point",winPoint)
                   .set("process_status",0)
                   .set("direction",direction);
           if (!Db.save("dctp_activity", record)) {
               throw new RuntimeException("添加失败");
           }

        }else {

            Record record = Db.findById("dctp_activity", id);
            //先还原
            Integer dbUpDownPoint = record.getInt("up_down_point");
            BigDecimal producePrice = record.getBigDecimal("produce_price");
            BigDecimal old = producePrice.subtract(BigDecimal.valueOf(dbUpDownPoint));

            BigDecimal newProducePrice = old.add(upDownPoint);
            Integer status = body.getInt("status");
            int r = Db.update("update dctp_activity set up_down_point = ?, produce_price = ?, win_point = ?,duration = ?,direction = ?,status = ? where id = ?  ", upDownPoint,newProducePrice,winPoint,duration,direction,
                    status,
                    id);
            if (r != 1) {
                throw new RuntimeException("更新失败");
            }
        }
        renderJson(JsonResult.success());
    }
}
